﻿using System;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using EntityFramework.Extensions;


namespace Model.Manager.DataBase.EntityFramework
{
    /// <summary>
    ///     实际就是Dbset类只是封装了
    ///     查询实现类：主要完成CRUD，自定义查询
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    internal class EntityOperator<TEntity> : Operator,IOperator<TEntity>
        where TEntity : class
    {
        /// <summary>
        ///     数据库容器
        /// </summary>
        private readonly DbContext _dbContext;

        /// <summary>
        ///     操作的数据实体集合
        /// </summary>
        private readonly DbSet<TEntity> _entitySet;

        /// <summary>
        ///     Linq查询
        /// </summary>
        private readonly IQueryable<TEntity> _queryable;



        /// <summary>
        ///     构造：通过数据容器创建
        /// </summary>
        /// <param name="dbContext"></param>
        public EntityOperator(DbContext dbContext)
        {
            _dbContext = dbContext;
            _entitySet = _dbContext.Set<TEntity>();
            _queryable = _entitySet.AsQueryable();
        }

        /// <summary>
        ///     用于支持Linq的复合查询
        /// </summary>
        /// <returns>Linq结果</returns>
        public IQueryable<TEntity> CreateQuery()
        {
            return _queryable;
        }

        /// <summary>
        ///     用于支持Linq的复合查询
        /// </summary>
        /// <param name="predicate">查询条件</param>
        /// <returns>Linq结果</returns>
        public IQueryable<TEntity> Query(Expression<Func<TEntity, bool>> predicate)
        {
            return _queryable.Where(predicate);
        }

        /// <summary>
        ///     批量删除
        /// </summary>
        /// <param name="predicate">判定语句</param>
        public void BatchDelete(Expression<Func<TEntity, bool>> predicate)
        {
            _entitySet.Delete(predicate);
        }

        /// <summary>
        ///     批量更新
        /// </summary>
        /// <param name="wherePredicate">更新条件</param>
        /// <param name="predicate">更新对象，只需要设置</param>
        public void BatchUpdate(Expression<Func<TEntity, bool>> wherePredicate, Expression<Func<TEntity, TEntity>> predicate)
        {
            Query(wherePredicate).Update(predicate);
        }

        /// <summary>
        ///     创建模型
        /// </summary>
        /// <param name="modelEntity"></param>
        public void Create(TEntity modelEntity)
        {
            _entitySet.Add(modelEntity);
        }

        /// <summary>
        ///     获取模型
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TEntity Retrieve(Guid id)
        {
            return _entitySet.Find(id);
        }

        /// <summary>
        ///     修改模型状态
        /// </summary>
        /// <param name="modelEntity">修改过的模型接口</param>
        [Obsolete]
        public void Modify(TEntity modelEntity)
        {
            _dbContext.Entry(modelEntity).State = System.Data.Entity.EntityState.Modified;
        }

        /// <summary>
        ///     移除模型
        /// </summary>
        /// <param name="modelEntity"></param>
        [Obsolete]
        public void Destroy(TEntity modelEntity)
        {
            _entitySet.Remove(modelEntity);
        }

        #region 释放


        private bool _mDisposed;

        /// <summary>
        ///     释放资源,并调用垃圾回收机制
        /// </summary>
        public override void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        ///     数据容器释放
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (!_mDisposed)
            {
                if (disposing)
                {
                    if (_dbContext != null)
                        _dbContext.Dispose();// Release managed resources
                }

                _mDisposed = true;
            }

        }

        ~EntityOperator()
        {
            Dispose(false);
        }

        #endregion
    }
}